package com.tanchengjin.admin.interceptions;

import com.tanchengjin.admin.SystemConstants;
import com.tanchengjin.admin.model.dao.AdminRoleMapper;
import com.tanchengjin.admin.model.pojo.AdminPermission;
import com.tanchengjin.admin.model.pojo.AdminUser;
import com.tanchengjin.admin.service.AdministratorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 权限拦截器
 *
 * @author tanchengjin
 */
public class AdminPermissionInterceptor implements HandlerInterceptor {

    @Autowired
    private AdminRoleMapper adminRoleMapper;

    @Autowired
    private AdministratorService administratorService;

    @Value("${app.admin.prefix}")
    private String adminPrefix;

    private final static Logger logger = LoggerFactory.getLogger(AdminPermissionInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        AdminUser currentAdminUser = getCurrentAdminUser(request);
        if (currentAdminUser == null) {
            response.sendRedirect("/admin/auth/login");
            return false;
        }
//        //超级管理员拥有所有权限
//        if (currentAdminUser.getId() != 1) {
//            if (!hasPermission(request, currentAdminUser.getId())) {
//                response.sendError(HttpStatus.FORBIDDEN.value());
//                return false;
//            }
//        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

    //获取当前登录的管理员
    private AdminUser getCurrentAdminUser(HttpServletRequest request) {
        Object attribute = request.getSession().getAttribute(SystemConstants.adminUserSessionKey);
        if (attribute instanceof AdminUser) {
            return (AdminUser) attribute;
        }
        return null;
    }

    /**
     * 校验权限
     *
     * @param request request
     * @param adminId 当前管理员id
     */
    @Deprecated
    private boolean hasPermission(HttpServletRequest request, int adminId) {

        List<AdminPermission> permissionList = administratorService.getPermissionByAdminId(adminId);

        String requestURI = request.getRequestURI();
        for (AdminPermission ps : permissionList) {

            String permission = ps.getHttpPath();

            if (!permission.startsWith("/")) {
                permission = "/" + permission;
            }
            //检验路径是否一致
            permission = adminPrefix + permission;
            if (requestURI.equals(permission)) {
                return checkHttpMethod(ps, request);
            }


            //校验/**多路径是否一致
            if (permission.endsWith("/**")) {
                int i = permission.lastIndexOf("/**");
                String substring = permission.substring(0, i);
                if (requestURI.startsWith(substring)) {
                    return checkHttpMethod(ps, request);
                }
            }

            int i = permission.indexOf("{id}");
            if (i >= 1) {
                String s = permission.replaceAll("\\{id}", "\\\\d+");
                if (requestURI.matches(s)) {
                    return checkHttpMethod(ps, request);
                }
            }

            //匹配单层路径
            int i1 = permission.indexOf("/*/");
            if (i1 >= 1) {
                String s = permission.replaceAll("/\\*/", "/\\\\w+/");
                if (requestURI.matches(s)) {
                    return checkHttpMethod(ps, request);
                }
            }


        }
        return false;
    }

    private boolean checkHttpMethod(AdminPermission adminPermission, HttpServletRequest request) {
        String httpMethod = adminPermission.getHttpMethod();
        if ("ALL".equals(httpMethod)) return true;
        return httpMethod.equals(request.getMethod());
    }
}
